import os
import json
import sys
from getpass import getpass
import subprocess

def parse_config(config_file):
    if not os.path.exists(config_file):
        default_config = {
            "hex_files": [
                {"offset_start": "0x00000000", "offset_end": "0x00008000", "file_name": "qboot_1st.bin"},
                {"offset_start": "0x00008000", "offset_end": "0x00009000", "file_name": "0x8000bin.bin"},
                {"offset_start": "0x00009000", "offset_end": "0x0000A000", "file_name": "0x9000bin.bin"},
                {"offset_start": "0x0000A000", "offset_end": "0x0000B000", "file_name": "0xA000bin.bin"},
                {"offset_start": "0x0000B000", "offset_end": "0x0000D000", "file_name": "0xB000bin.bin"},
                {"offset_start": "0x0000D000", "offset_end": "0x00025000", "file_name": "qboot_2nd.bin"},
                {"offset_start": "0x00025000", "offset_end": None, "file_name": "APP_X_R1.bin"}
            ]
        }

        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump(default_config, f, indent=4, ensure_ascii=False)

    with open(config_file, 'r', encoding='utf-8') as f:
        config = json.load(f)

    img_directory = os.path.join(os.path.dirname(os.path.abspath(config_file)), 'img')
    hex_files = []
    for entry in config['hex_files']:
        offset_start = entry['offset_start']
        offset_end = entry['offset_end']
        file_name = entry['file_name']
        file_path = os.path.join(img_directory, file_name)
        hex_files.append((offset_start, offset_end, file_path))

    return hex_files


def convert_binary_to_hex(bin_file, address):
    bin_file_path = os.path.join('img', bin_file)
    if not os.path.exists(bin_file_path):
        return f'{bin_file_path} 不存在！'

    hex_file = os.path.splitext(bin_file)[0] + '.hex'
    hex_file_path = os.path.join('img', hex_file)
    command = ['srec_cat.exe', bin_file_path, '-Binary', '-offset', address, '-o', hex_file_path, '-Intel']

    # print(f"生成的合并命令为：{command_str}")
    # status = os.system(command_str)
    # if status != 0:
    #     return f'{bin_file} 转换失败！'
    try:
        subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    except subprocess.CalledProcessError as e:
        return f'{bin_file} 转换失败: {e.stderr.decode().strip()}'

    return None



def merge_hex_files(hex_files, output_file):
    for index, hex_file in enumerate(hex_files):
        hex_file_path = os.path.join('img', hex_file[2])

        if not os.path.exists(hex_file_path):
            return f'{hex_file[2]} 不存在！'
        else:
            file_name, file_ext = os.path.splitext(hex_file[2])
            modified_file_name = f'{file_name}.hex'
            hex_files[index] = (hex_file[0], hex_file[1], modified_file_name)

    command = ['srec_cat.exe']

    for hex_file in hex_files:
        offset_start = hex_file[0]
        offset_end = hex_file[1]
        file_name = hex_file[2]
        file_path = os.path.join('img', file_name)

        if offset_end is not None:
            command.extend([file_path, '-Intel', '-fill', '0xff', f'{offset_start}', f'{offset_end}'])
        else:
            command.extend([file_path, '-Intel'])

    command.extend(['-o', output_file, '-Intel'])

    command_str = ' '.join(command)
    #print(f"生成的合并命令为：{command_str}")

    status = os.system(command_str)
    if status != 0:
        return f'{output_file} 合并失败！'
    return None




def delete_hex_files(keep_file):
    img_directory = 'img'
    for file_name in os.listdir(img_directory):
        if file_name.endswith('.hex') and file_name != keep_file:
            file_path = os.path.join(img_directory, file_name)
            os.remove(file_path)



def main(config_file):
    error_msgs = []
    
    hex_files = parse_config(config_file)

    
    # 获取 config.json 文件所在的目录路径
    config_dir = os.path.dirname(config_file)
    
    # 设置合并后的文件路径为与 config.json 同一目录下的 MergedHexFile.hex
    output_file = os.path.join(config_dir, 'MergedHexFile.hex')
    #print(hex_files)
    
    # 构造 img 目录的路径，检测 img 目录是否存在，如果不存在则创建
    img_directory = os.path.join(config_dir, 'img')
    if not os.path.exists(img_directory):
        os.mkdir(img_directory)
    
    # 转换二进制文件为十六进制文件
    for offset_start, offset_end, bin_file in hex_files:
        # 构造输入二进制文件路径，相对于 config.json 的位置
        bin_file_path = os.path.join(config_dir, bin_file)
        
        error_msg = convert_binary_to_hex(bin_file_path, offset_start)
        if error_msg is not None:
            error_msgs.append(error_msg)
    
    # 合并十六进制文件
    error_msg = merge_hex_files(hex_files, output_file)
    if error_msg is not None:
        error_msgs.append(error_msg)

    delete_hex_files(output_file)

    if len(error_msgs) == 0:
        print('hex文件合成成功：' + output_file)
        return None
    else:
        print('以下错误发生了：')
        for error_msg in error_msgs:
            print(error_msg)
        return error_msgs  # 返回错误信息列表

    # getpass("按下任意键继续...")
    # sys.exit()

if __name__ == '__main__':
    main('D:\\txjwork\\pylink\\embedded-system-tools\\output\\config.json')



# 使用方式
# import MergedHex

# MergedHexFile.main()
